#ifndef __MY_MAP_SET_HPP__
#define __MY_MAP_SET_HPP__

#include "MyHash.hpp"

namespace my_maphash
{
    using namespace open_hash;

    template<class K, class V, class hash = HashFunc<K>>
    class Map
    {
        struct KeyofT
        {
            const K& operator()(const std::pair<K, V>& kv)
            {
                return kv.first;
            }
        };
    private:
        HashBucket<K, std::pair<K, V>, hash, KeyofT> _hb;
    public:
        // 声明迭代器
        typedef __HashBucketIterator<K, std::pair<K, V>, hash, KeyofT> Iterator;

        Iterator begin()
        {
            return _hb.begin();
        }

        Iterator end()
        {
            return _hb.end();
        }

        std::pair<Iterator, bool> insert(const std::pair<K, V>& kv)
        {
            return _hb.insert(kv);
        }

        bool erase(const K& key)
        {
            return _hb.erase(key);
        }

        Iterator find(const K& key)
        {
            return _hb.find(key);
        }

        // 重点
        V& operator[](const K& key)
        {
            // 如果传入新的key，我们可以适应默认值V进行初始化返回
            std::pair<Iterator, bool> values = _hb.insert(std::make_pair(key, V()));
            return (values.first)->second;  // 返回值 因为Iterator解引用是pair结构哦
        }
    };
}

namespace my_sethash
{
    using namespace open_hash;

    template<class K, class hash = HashFunc<K>>
    class Set
    {
        struct KeyofT
        {
            const K& operator()(const K& key)
            {
                return key;
            }
        };
    private:
        HashBucket<K, K, hash, KeyofT> _hb;
    public:
        // 声明迭代器
        typedef __HashBucketIterator<K, K, hash, KeyofT> Iterator;

        Iterator begin()
        {
            return _hb.begin();
        }

        Iterator end()
        {
            return _hb.end();
        }

        std::pair<Iterator, bool> insert(const K& key)
        {
            return _hb.insert(key);
        }

        bool erase(const K& key)
        {
            return _hb.erase(key);
        }

        Iterator find(const K& key)
        {
            return _hb.find(key);
        }
    };
}

#endif